package com.siecom.transport.handler;

import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.SystemClock;
import android.provider.Settings;
import android.support.v4.content.FileProvider;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Toast;

import com.siecom.constconfig.ConstDefine;
import com.siecom.hostservice.MainActivity;
import com.siecom.module.DeviceCallback;
import com.siecom.module.DeviceInterface;
import com.siecom.proto.Message;
import com.siecom.tool.FileUnits;
import com.siecom.tool.LogUtil;
import com.siecom.tool.MD5;
import com.siecom.transport.CommServer;
import com.siecom.transport.bluetooth.BlueServer;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URI;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * Created by zhq on 2017/2/13.
 */

public class UpdateHandler implements ServiceHandler  {

    private final static String TAG = UpdateHandler.class.getSimpleName();
    private static ExecutorService threadPool = Executors.newFixedThreadPool(1);
    private CommServer server;
    private int total= 0;
    private int num = 0;
    String fileName ="";
    String mMd5 = "";
    @Override
    public void onReceive(CommServer server, Message.siecomproto msg ,String message) {
        this.server = server;
        LogUtil.e("UpdateHandler", "onReceive");
        switch (msg.getCmd()) {
            case ConstDefine.UPDATE_FW_REQUEST:
                LogUtil.e(TAG,"UPDATE_FW_REQUEST=" + "----");
                String respond = msg.getRequest();

                try {
                    JSONObject jb = new JSONObject(respond);;
                    fileName = jb.getString("name");
                    if(jb.has("total")){
                        total = jb.getInt("total");
                    }
                    if(jb.has("num")){
                        num = jb.getInt("num");
                    }
                    if(jb.has("md5")){
                        mMd5 = jb.getString("md5");
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }
                LogUtil.e(TAG,"fileName="+fileName);
                if(fileName.endsWith("bin")){

                    updateFw(msg);
                }else if (fileName.endsWith("apk")){
                    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
                        if (MainActivity.context.getPackageManager().canRequestPackageInstalls()){
                            updateApk(msg);
                        }else {
                            Uri uri = Uri.parse("package:" + MainActivity.context.getPackageName());
                            Intent intent = new Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES,uri);
                            MainActivity.context.startActivity(intent);
                            Toast.makeText(MainActivity.context,"请允许安装未知来源程序后再次升级" ,Toast.LENGTH_LONG).show();
                            try {
                                json = new JSONObject();
                                json.put("error","请允许安装未知来源程序后再次尝试升级");
                            } catch (JSONException e) {
                                e.printStackTrace();
                            }
                            com.siecom.proto.Message.siecomproto.Builder msgBuilder = com.siecom.proto.Message.siecomproto.newBuilder();
                            msgBuilder.setModule(ConstDefine.UPDATE_MODULE);
                            msgBuilder.setMsgid(msg.getMsgid());
                            msgBuilder.setCmd(msg.getCmd() + 1);
                            msgBuilder.setRespond(json.toString());
                            msgBuilder.setError(-1);
                            com.siecom.proto.Message.siecomproto respondMsg = msgBuilder.build();
                            server.sendToRemote(respondMsg);
                        }

                    }else {
                        updateApk(msg);
                    }

                }
                break;

        }
    }

    byte apkData[];
    FileOutputStream fileOutputStream;
    Runnable r = null;
    Runnable writeRunable = null;
    File apkFile = null;
    File mBinFile = null;
    int mProgress = 0;
    JSONObject json = new JSONObject();


    public void updateApk(Message.siecomproto msg){

         r = new Runnable() {
            @Override
            public void run() {

                if(num == 1){
                    FileUnits fileUnits = new FileUnits();
                    apkFile = fileUnits.createSDFile(fileName);
                    try {
                        fileOutputStream = new FileOutputStream(apkFile);
                    } catch (FileNotFoundException e) {
                        e.printStackTrace();
                    }
                }
                LogUtil.e(TAG,"total="+total + "----num=" + num);
                if(num <= total){
                    int progress = (num *100)/total;
                    LogUtil.e(TAG,"progress==" + progress);
                    if(progress != mProgress){
                        mProgress = progress;

                        try {

                            json.put("flag",2);
                            json.put("data",progress);

                        }catch (JSONException e){
                            e.printStackTrace();
                        }
                        LogUtil.e(TAG,"progress send");
                        com.siecom.proto.Message.siecomproto.Builder msgBuilder = com.siecom.proto.Message.siecomproto.newBuilder();
                        msgBuilder.setModule(ConstDefine.UPDATE_MODULE);
                        msgBuilder.setMsgid(msg.getMsgid());
                        msgBuilder.setCmd(msg.getCmd() + 1);
                        msgBuilder.setRespond(json.toString());
                        msgBuilder.setError(0);
                        com.siecom.proto.Message.siecomproto respondMsg = msgBuilder.build();
                        LogUtil.e(TAG,"sendToRemote");
                        server.sendToRemote(respondMsg);
                    }
                    apkData = msg.getExtion().toByteArray();
                    writeFile(apkData);

                }
            }
        };
        threadPool.submit(r);

        if(num == total){
            SystemClock.sleep(10);
            LogUtil.e(TAG,"apkFile.getAbsolutePath：" + apkFile.getAbsolutePath());
            if(apkFile != null){
                String md5 = MD5.getMD5Three(apkFile.getAbsolutePath());
                LogUtil.e(TAG,"MD5 分别是：" + md5 + "--" + mMd5 + "--" +  md5.equals(mMd5));
                String fullName = apkFile.getAbsolutePath();
                boolean isSuc = install(MainActivity.context,fullName);
                if(isSuc){
                    JSONObject json = new JSONObject();
                    try {
                        json.put("flag",0);
                    }catch (JSONException e){
                        e.printStackTrace();
                    }
                    com.siecom.proto.Message.siecomproto.Builder msgBuilder = com.siecom.proto.Message.siecomproto.newBuilder();
                    msgBuilder.setModule(ConstDefine.UPDATE_MODULE);
                    msgBuilder.setMsgid(msg.getMsgid());
                    msgBuilder.setRespond(json.toString());
                    msgBuilder.setCmd(msg.getCmd() + 1);
                    msgBuilder.setError(0);
                    com.siecom.proto.Message.siecomproto respondMsg = msgBuilder.build();
                    server.sendToRemote(respondMsg);
                }else {
                    LogUtil.e(TAG,"安装失败");
                }

            }
            try {
                fileOutputStream.close();
                fileOutputStream = null;
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }

    public void writeFile(byte[] apkData){
        writeRunable = new Runnable() {
            @Override
            public void run() {
                try {
                    LogUtil.e(TAG,"写文件钱："+apkData.length);
                    fileOutputStream.write(apkData,0,apkData.length);
                    LogUtil.e(TAG,"写文件后："+apkData.length);

                } catch (IOException e) {
                    e.printStackTrace();
                    LogUtil.e(TAG,"写文件异常："+e.getMessage());
                }
            }
        };
        threadPool.submit(writeRunable);
    }


    public void updateFw( Message.siecomproto msg){
          Runnable r  = new Runnable() {
              @Override
              public void run() {
                  if(num == 1){
                      FileUnits fileUnits = new FileUnits();
                      mBinFile = fileUnits.createSDFile(fileName);
                      try {
                          fileOutputStream = new FileOutputStream(mBinFile);
                      } catch (FileNotFoundException e) {
                          e.printStackTrace();
                      }
                  }
                  LogUtil.e(TAG,"total="+total + "----num=" + num);
                  if(num <= total){
                      int progress = (num *100)/total;
                      LogUtil.e(TAG,"progress==" + progress);
                      if(progress != mProgress){
                          mProgress = progress;

                          try {

                              json.put("flag",2);
                              json.put("data",progress);

                          }catch (JSONException e){
                              e.printStackTrace();
                          }

                          LogUtil.e(TAG,"progress send");
                          com.siecom.proto.Message.siecomproto.Builder msgBuilder = com.siecom.proto.Message.siecomproto.newBuilder();
                          msgBuilder.setModule(ConstDefine.UPDATE_MODULE);
                          msgBuilder.setMsgid(msg.getMsgid());
                          msgBuilder.setCmd(msg.getCmd() + 1);
                          msgBuilder.setRespond(json.toString());
                          msgBuilder.setError(0);
                          com.siecom.proto.Message.siecomproto respondMsg = msgBuilder.build();
                          LogUtil.e(TAG,"sendToRemote");
                          server.sendToRemote(respondMsg);
                      }
                      apkData = msg.getExtion().toByteArray();
                      writeFile(apkData);

                  }
//                  byte[] FwData  =  msg.getExtion().toByteArray();
//                  String fileName = msg.getRequest();
//                  LogUtil.e(TAG,"fileName=" + fileName + "----" + FwData.length);
//                  FileUnits fileUnits = new FileUnits();
//
//                  File file = fileUnits.createSDFile(fileName);
//                  try {
//                      FileOutputStream  outputStream = new FileOutputStream(file);
//                      outputStream.write(FwData);
//                  } catch (IOException e) {
//                      e.printStackTrace();
//                      com.siecom.proto.Message.siecomproto.Builder msgBuilder = com.siecom.proto.Message.siecomproto.newBuilder();
//                      msgBuilder.setModule(ConstDefine.UPDATE_MODULE);
//                      msgBuilder.setMsgid(msg.getMsgid());
//                      msgBuilder.setCmd(msg.getCmd() + 1);
//                      msgBuilder.setRespond(e.getMessage());
//                      msgBuilder.setError(e.hashCode());
//                      com.siecom.proto.Message.siecomproto respondMsg = msgBuilder.build();
//                      server.sendToRemote(respondMsg);
//                  }

              }
          };
        threadPool.submit(r);
        if(num == total){
            LogUtil.e(TAG,"filePath=" + mBinFile.getAbsolutePath() + "----" );

            String md5 = MD5.getMD5Three(mBinFile.getAbsolutePath());
            LogUtil.e(TAG,"MD5 分别是：" + md5 + "--" + mMd5 + "--" +  md5.equals(mMd5));
            String path = Environment.getExternalStorageDirectory().getAbsolutePath()+File.separator+fileName;
//                  path = "/sdcard/Download/US831_MH1902_App_V1.0.0_release_keyboard4x4_20191023.bin";
            path = mBinFile.getAbsolutePath();
            DeviceInterface.updateFw(path, new DeviceCallback() {
                @Override
                public void onStart() {
                    JSONObject json = new JSONObject();
                    try {
                        json.put("flag",2);
                    }catch (JSONException e){
                        e.printStackTrace();
                    }
                    com.siecom.proto.Message.siecomproto.Builder msgBuilder = com.siecom.proto.Message.siecomproto.newBuilder();
                    msgBuilder.setModule(ConstDefine.UPDATE_MODULE);
                    msgBuilder.setMsgid(msg.getMsgid());
                    msgBuilder.setCmd(msg.getCmd() + 1);
                    msgBuilder.setError(0);
                    com.siecom.proto.Message.siecomproto respondMsg = msgBuilder.build();
                    server.sendToRemote(respondMsg);

                }

                @Override
                public void onError(Bundle bundle) {
                    com.siecom.proto.Message.siecomproto.Builder msgBuilder = com.siecom.proto.Message.siecomproto.newBuilder();
                    msgBuilder.setModule(ConstDefine.UPDATE_MODULE);
                    msgBuilder.setMsgid(msg.getMsgid());
                    msgBuilder.setCmd(msg.getCmd() + 1);
                    msgBuilder.setRespond(bundle.getString("message"));
                    msgBuilder.setError(bundle.getInt("code"));
                    com.siecom.proto.Message.siecomproto respondMsg = msgBuilder.build();
                    server.sendToRemote(respondMsg);

                }

                @Override
                public void onSuccess(Bundle bundle) {
                    JSONObject json = new JSONObject();
                    try {
                        json.put("flag",1);
                        json.put("data", bundle.getInt("data"));
                    }catch (JSONException e){
                        e.printStackTrace();
                    }
                    com.siecom.proto.Message.siecomproto.Builder msgBuilder = com.siecom.proto.Message.siecomproto.newBuilder();
                    msgBuilder.setModule(ConstDefine.UPDATE_MODULE);
                    msgBuilder.setMsgid(msg.getMsgid());
                    msgBuilder.setCmd(msg.getCmd() + 1);
                    msgBuilder.setRespond(json.toString());
                    msgBuilder.setError(0);
                    com.siecom.proto.Message.siecomproto respondMsg = msgBuilder.build();
                    server.sendToRemote(respondMsg);

                }

                @Override
                public void onCompleted(Bundle bundle) {
                    JSONObject json = new JSONObject();
                    try {
                        json.put("flag",0);
                    }catch (JSONException e){
                        e.printStackTrace();
                    }
                    com.siecom.proto.Message.siecomproto.Builder msgBuilder = com.siecom.proto.Message.siecomproto.newBuilder();
                    msgBuilder.setModule(ConstDefine.UPDATE_MODULE);
                    msgBuilder.setMsgid(msg.getMsgid());
                    msgBuilder.setRespond(json.toString());
                    msgBuilder.setCmd(msg.getCmd() + 1);
                    msgBuilder.setError(0);
                    com.siecom.proto.Message.siecomproto respondMsg = msgBuilder.build();
                    server.sendToRemote(respondMsg);

                }

            },false);

            try {
                fileOutputStream.close();
                fileOutputStream = null;
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }

    public static boolean install(Context con, String filePath) {
        try {
            if(TextUtils.isEmpty(filePath))

                return false;
            File file = new File(filePath);
            if(!file.exists()){
                return false;
            }
            Intent intent = new Intent(Intent.ACTION_VIEW);
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);//增加读写权限
            }
            intent.setDataAndType(getPathUri(con, filePath), "application/vnd.android.package-archive");
            con.startActivity(intent);
        } catch (Exception e) {
            e.printStackTrace();
            Toast.makeText(con, "安装失败，请重新下载", Toast.LENGTH_LONG).show();
            return false;
        } catch (Error error) {
            error.printStackTrace();
            Toast.makeText(con, "安装失败，请重新下载", Toast.LENGTH_LONG).show();
            return false;
        }
        return true;
    }
    public static Uri getPathUri(Context context, String filePath) {
        Uri uri;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            String packageName = context.getPackageName();
            uri = FileProvider.getUriForFile(context, packageName + ".fileProvider", new File(filePath));
        } else {
            uri = Uri.fromFile(new File(filePath));
        }
        return uri;
    }


}
